<?php

namespace app\admin\controller;

use app\admin\validate\SysRole as SysRoleValidate;
use app\common\business\SysMenu as SysMenuBus;
use app\common\business\SysRole as SysRoleBus;
use app\common\business\SysUser;
use app\common\lib\toCamelCase;
use app\common\model\mysql\SysRoleDept;
use app\common\model\mysql\SysRoleMenu;
use app\common\model\mysql\SysUserRole;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use think\facade\Db;

class SysRole extends AuthBase
{
    //获取角色列表查询条件
    public function roleListSearch(){
        $where = [];
        // 获取分页参数
        $page = $this->request->get('pageNum', 1);
        $limit = $this->request->get('pageSize', 10);
        $roleName = $this->request->get('roleName',"");
        $roleKey = $this->request->get('roleKey',"");
        $status = $this->request->get("status","");
        $params = $this->request->get('params',"");
        if($roleName){
            $where[] = ['role_name', 'like', '%'.$roleName.'%'];
        }
        if($roleKey){
            $where[] = ['role_key', 'like', '%'.$roleKey.'%'];
        }
        if ($status !== null && $status !== '') {
            // 如果$status不为null且不为空字符串，则添加条件到$where数组
            $where[] = ["status", "=", $status];
        }
        $where[] = ["del_flag","=",'0'];
        if($params){
            $where[] = ['create_time',">=",$params['beginTime']." 00:00:00"];
            $where[] = ['create_time',"<=",$params['endTime']." 23:59:59"];
        }
        $data = [
            'page'=>$page,
            'limit'=>$limit,
            'where'=>$where
        ];
        return $data;
    }
    //角色列表
    public function roleList(){
        try {
            $searchData = $this->roleListSearch();
            $roleData = (new SysRoleBus())->getNormalRole($searchData['where'],'*',$searchData['limit'],$searchData['page']);
            $roleData = (new toCamelCase())->toCamelCaseArray($roleData);
        }catch (\Exception $e){
            $roleData = [];
        }
        return show(config("status.success"),"角色列表",$roleData);
    }

    //角色添加
    public function roleAdd(){
        if (!$this->request->isPost()) {
            return show(config("status.error"), "请求方式错误");
        }
        // 参数校验
        $params = $this->request->post();
        $data = [
            'role_name' => $params['roleName'] ?? '',
            'role_key' => $params['roleKey'] ?? '',
            'role_sort' => $params['roleSort'] ?? 0,
            'data_scope' => $params['dataScope'] ?? '1',
            'dept_check_strictly' => (int) ($params['deptCheckStrictly'] ?? 0),
            'menu_check_strictly' => (int) ($params['menuCheckStrictly'] ?? 0),
            'remark' => $params['remark'] ?? null,
            'status' => $params['status'] ?? 0,
        ];
        $validate = new SysRoleValidate();
        if (!$validate->check($data)) {
            return show(config("status.error"), $validate->getError());
        }
        try {
            $result = (new SysRoleBus())->addRole($data);
            if (!$result) {
                return show(config("status.error"), "添加角色失败");
            }
            (new SysRoleMenu())->insertAllRoleMenu($params['menuIds'] ?? [], $result);
            return show(config("status.success"), "新增成功", $result);
        } catch (\Exception $e) {
            return show(config('status.error'), $e->getMessage());
        }
    }

    //角色修改
    public function roleEdit(){
        $params = request()->param();
        // 验证 roleId 是否存在
        if (empty($params['roleId'])) {
            return show(config("status.error"), "角色ID不能为空");
        }
        $data = [
            'role_name' => $params['roleName'] ?? '',
            'role_key' => $params['roleKey'] ?? '',
            'role_sort' => $params['roleSort'] ?? 0,
            'data_scope' => $params['dataScope'] ?? '1',
            'dept_check_strictly' => (int) ($params['deptCheckStrictly'] ?? 0),
            'menu_check_strictly' => (int) ($params['menuCheckStrictly'] ?? 0),
            'remark' => $params['remark'] ?? null,
            'status' => $params['status'] ?? 0,
        ];
        try {
            Db::startTrans(); // 开始事务
            // 更新角色信息
            $roleId = $params['roleId'];
            $updateResult = (new SysRoleBus())->updateById($roleId, $data);
            if (!$updateResult) {
                return show(config("status.error"), "修改角色失败");
            }
            // 删除旧的角色与菜单权限
            (new SysRoleMenu())->deleteAllRoleMenu($roleId);
            // 添加新的角色与菜单权限
            (new SysRoleMenu())->insertAllRoleMenu($params['menuIds'] ?? [], $roleId);
            // 提交事务
            Db::commit();
            return show(config("status.success"), "修改成功", $roleId);
        }catch (\Exception $e){
            // 回滚事务
            Db::rollback();
            return show(config('status.error'),$e->getMessage());
        }
    }

    //角色详情
    public function roleDetails(){
        $role = $this->request->param("role","","trim");
        if(empty($role)){
            return show(config("status.error"),"参数不能为空");
        }
        try {
            $roleData = (new SysRoleBus())->getRoleById($role);
            $roleData = (new toCamelCase())->toCamelCaseArray($roleData);
        }catch (\Exception $e){
            $roleData = [];
        }
        return show(config("status.success"),"角色详情",$roleData);
    }

    //删除角色
    public function roleDel(){
        $role = $this->request->param("role","","trim");
        if(empty($role)){
            return show(config("status.error"),"参数不能为空");
        }
        try {
            $result = (new SysRoleBus())->DelRoleIds($role);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"删除成功",$result);
    }

    //根据角色ID查询菜单下拉树结构
    public function roleMenuTreeselect(){
        $roleId = $this->request->param("roleId","","trim");
        if(empty($roleId)){
            return show(config("status.error"),"参数不能为空");
        }
        $checkedKeys = (new SysRoleMenu())->getRoleMenuIdArray($roleId);
        $menus = (new SysMenuBus())->menuTree();
        $data = [
            'checkedKeys'=>$checkedKeys,
            'menus'=>$menus,
        ];
        return show(config("status.success"),"ok",$data);
    }

    //根据角色ID查询部门树结构
    public function roleDeptTreeselect(){
        $roleId = $this->request->param("roleId","","trim");
        if(empty($roleId)){
            return show(config("status.error"),"参数不能为空");
        }
        $checkedKeys = (new SysRoleDept())->getRoleDeptIdArray($roleId);
        $deptParentId = (new \app\common\business\SysDept())->deptParentId();
        // 去除$deptParentId中的0
        $deptParentId = array_filter($deptParentId, function($value) {
            return $value !== 0;
        });
        // 去除$deptParentId中的重复项（虽然array_diff会自动处理，但这里为了清晰展示）
        $deptParentId = array_unique($deptParentId);
        // 使用array_diff找出$checkedKeys中存在但$deptParentId中不存在的元素
        $result = array_diff($checkedKeys, $deptParentId);
        // 重新从0开始索引结果数组
        $result = array_values($result);
        $depts = (new \app\common\business\SysDept())->deptTree();
        $data = [
            'checkedKeys'=>$result,
            'depts'=>$depts,
        ];
        return show(config("status.success"),"ok",$data);
    }

    //导出角色信息
    public function exportRole(){
        $searchData = $this->roleListSearch();
        $roleData = (new SysRoleBus())->getNormalRole($searchData['where'],'*',$searchData['limit'],$searchData['page']);
        // 创建Spreadsheet对象
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        $sheet->mergeCells('A1:F1');
        $sheet->setCellValue('A1', '角色数据');
        // 设置表头
        $header = ['角色序号', '角色名称', '角色权限', '角色排序', '数据范围','角色状态'];
        $row = 2;
        $col = 1; // 列索引，从A列开始
        foreach ($header as $column) {
            // 使用setCellValueByColumnAndRow时，第二个参数是列号（整数），第三个参数是值
            $sheet->setCellValueByColumnAndRow($col, $row, $column);
            $col++; // 移动到下一列
        }
        // 使用循环设置列宽
        $columns = ['A', 'B', 'C', 'D', 'E', 'F']; // 定义需要设置宽度的列
        foreach ($columns as $column) {
            $sheet->getColumnDimension($column)->setWidth(15);
        }
        // 填充数据
        $row = 3;
        foreach ($roleData['data'] as $post) {
            $post['status'] = $post['status'] === '0' ? "正常" : "停用";
            if($post['data_scope'] == '1'){
                $data_scope = '全部数据权限';
            }elseif($post['data_scope'] == '2'){
                $data_scope = '自定数据权限';
            }elseif($post['data_scope'] == '3'){
                $data_scope = '本部门数据权限';
            }else{
                $data_scope = '本部门及以下数据权限';
            }
            $sheet->setCellValue('A' . $row, $post['role_id']);
            $sheet->setCellValue('B' . $row, $post['role_name']);
            $sheet->setCellValue('C' . $row, $post['role_key']);
            $sheet->setCellValue('D' . $row, $post['role_sort']);
            $sheet->setCellValue('E' . $row, $data_scope);
            $sheet->setCellValue('F' . $row, $post['status']);
            // 填充其他字段
            $row++;
        }
        $row = $row-1;
        $SpreadsheetObj = new \app\common\lib\Spreadsheet();
        $sheet->getStyle('A1')->applyFromArray($SpreadsheetObj->fontArray('FF000000',18));
        $sheet->getStyle('A2:F2')->applyFromArray($SpreadsheetObj->fillArray("808080"));
        $sheet->getStyle('A2:F2')->applyFromArray($SpreadsheetObj->fontArray("FFFFFFFF"));
        $sheet->getStyle('A1' . ':F' . $row)->applyFromArray($SpreadsheetObj->styleBorderArray());
        $sheet->getStyle('A1' . ':F' . $row)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);

        // 创建Writer对象，并保存为xlsx文件
        $writer = new Xlsx($spreadsheet);
        // 设置响应头
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="post.xlsx"');
        header('Cache-Control: max-age=0');
        // 导出
        $writer->save('php://output');
        exit;
    }

    //更改角色状态
    public function changeStatus(){
        $roleId = $this->request->param("roleId","","trim");
        $status = $this->request->param("status","","trim");
        // 验证 roleId 是否存在
        if (empty($roleId)) {
            return show(config("status.error"), "角色ID不能为空");
        }
        if ($status == "") {
            return show(config("status.error"), "角色状态不能为空");
        }
        try {
            $result = (new SysRoleBus())->changeStatusRole($roleId,$status);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"操作成功",$result);
    }

    //角色分配数据权限
    public function dataRoleScope(){
        $params = request()->param();
        // 验证 roleId 是否存在
        if (empty($params['roleId'])) {
            return show(config("status.error"), "角色ID不能为空");
        }
        $data = [
            'role_name' => $params['roleName'] ?? '',
            'role_key' => $params['roleKey'] ?? '',
            'role_sort' => $params['roleSort'] ?? 0,
            'data_scope' => $params['dataScope'] ?? '1',
            'dept_check_strictly' => (int) ($params['deptCheckStrictly'] ?? 0),
            'menu_check_strictly' => (int) ($params['menuCheckStrictly'] ?? 0),
            'remark' => $params['remark'] ?? null,
            'status' => $params['status'] ?? 0,
        ];
        try {
            Db::startTrans(); // 开始事务
            // 更新角色信息
            $roleId = $params['roleId'];
            $updateResult = (new SysRoleBus())->updateById($roleId, $data);
            if (!$updateResult) {
                return show(config("status.error"), "修改角色失败");
            }
            // 删除旧的角色与菜单权限
            (new SysRoleDept())->deleteAllRoleDept($roleId);
            // 添加新的角色与菜单权限
            (new SysRoleDept())->insertAllRoleDept($params['deptIds'] ?? [], $roleId);
            // 提交事务
            Db::commit();
            return show(config("status.success"), "操作成功", $roleId);
        }catch (\Exception $e){
            // 回滚事务
            Db::rollback();
            return show(config('status.error'),$e->getMessage());
        }
    }

    //角色分配用户列表
    public function allocatedList(){
        $where = [];
        $roleId = $this->request->get('roleId',"");
        $userIds = (new SysUserRole())->getUserIds($roleId);
        // 获取分页参数
        $page = $this->request->get('pageNum', 1);
        $limit = $this->request->get('pageSize', 10);
        $userName = $this->request->get('userName',"");
        $phonenumber = $this->request->get("phonenumber","");
        if($userName){
            $where[] = ['user_name', 'like', '%'.$userName.'%'];
        }
        if($phonenumber){
            $where[] = ['phonenumber', 'like', '%'.$phonenumber.'%'];
        }
        if(empty($userIds)){
            return show(config("status.success"),"角色分配用户列表",[]);
        }
        $where[] = ['user_id','in',$userIds];
        try {
            $userData = (new SysUser())->getNormalUser($where,'*',$limit,$page);
            $userData = (new toCamelCase())->toCamelCaseArray($userData);
        }catch (\Exception $e){
            $userData = [];
        }
        return show(config("status.success"),"角色分配用户列表",$userData);
    }

    //角色分配添加用户列表
    public function unallocatedList(){
        $where = [];
        $roleId = $this->request->param('roleId',"");
        $userIds = (new SysUserRole())->getUserIds($roleId);
        // 获取分页参数
        $page = $this->request->param('pageNum', 1);
        $limit = $this->request->param('pageSize', 10);
        $userName = $this->request->param('userName',"");
        $phonenumber = $this->request->param("phonenumber","");
        if($userName){
            $where[] = ['user_name', 'like', '%'.$userName.'%'];
        }
        if($phonenumber){
            $where[] = ['phonenumber', 'like', '%'.$phonenumber.'%'];
        }
        if($userIds){
            $where[] = ['user_id','not in',$userIds];
        }
        try {
            $userData = (new SysUser())->getNormalUser($where,'*',$limit,$page);
            $userData = (new toCamelCase())->toCamelCaseArray($userData);
        }catch (\Exception $e){
            $userData = [];
        }
        return show(config("status.success"),"角色分配添加用户列表",$userData);
    }

    //角色分配添加用户
    public function selectAllRoleUser(){
        $roleId = $this->request->param('roleId',"");
        $userIds = $this->request->param('userIds', "");
        if(empty($roleId) || empty($userIds)){
            return show(config("status.error"),"参数不能为空");
        }
        try {
            $userIds = explode(',', $userIds);
            $result = (new SysUserRole())->insertAllRoleUser($userIds,$roleId);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"操作成功",$result);
    }

    //取消角色分配用户授权
    public function authUserCancel(){
        $roleId = $this->request->param('roleId',"");
        $userId = $this->request->param('userId', "");
        if(empty($roleId) || empty($userId)){
            return show(config("status.error"),"参数不能为空");
        }
        try {
            $result = (new SysUserRole())->deleteRoleUser($userId,$roleId);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"操作成功",$result);
    }

    //批量取消角色分配用户授权
    public function authUserCancelAll(){
        $roleId = $this->request->param('roleId',"");
        $userIds = $this->request->param('userIds', "");
        if(empty($roleId) || empty($userIds)){
            return show(config("status.error"),"参数不能为空");
        }
        try {
            $userIds = explode(',', $userIds);
            $result = (new SysUserRole())->deleteAllRoleUser($userIds,$roleId);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"操作成功",$result);
    }
}
